home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 41.zip / BS1 part 41 / Compute`s Amiga resource 1.adf / Source / Mr.Gadget / mrgadget.c
C/C++ Source or Header  |  1989-02-07  |  14KB  |  472 lines

  1. /*
  2.    MrGadget
  3.    Copyright 1989 COMPUTE! Publications, Inc.
  4.    All Rights Reserved
  5. */
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include <intuition/intuition.h>
  10. #include <exec/exec.h>
  11.  
  12. #ifdef SKIP
  13.    This set of functions was created for saving time in program creation.
  14. It will open a window with the requested string gadgets and then the requested
  15. Boolean gadgets. As many MrGadget windows can be opened at a time as needed as
  16. long as a each window has it's own MrGadget structure.
  17.    A number of cautions are to be taken if this system is used: Do not request
  18. any gadgets with titles longer than 70 characters or any string gadgets
  19. that accept more than 70 characters. Do not request more gadgets than will fit
  20. in the window vertically. The window is 200 pixels tall. String gadgets are 26
  21. pixels tall and boolean gadgets are 20 pixels tall. The first gadget starts 36
  22. pixels down from the top (we leave room for a message), so you have 164 pixels
  23. maximum (200 - 36 = 164) to work with.
  24. 164 / 26 = 6 string gadgets in the window at one time
  25. 164 / 20 = 8 boolean gadget in the window at one time 
  26. or a mixture of both.
  27. #endif
  28.  
  29. /* menu bar for Yes or No window */
  30. struct IntuiText MrGadMenuT1 = {3,1,COMPLEMENT,0,0,NULL," NO",NULL};
  31. struct MenuItem MrGadItem2 =
  32. {NULL,0,9,96,8,ITEMTEXT | COMMSEQ | ITEMENABLED | HIGHCOMP,0,
  33.         (APTR)&MrGadMenuT1,NULL,'N',NULL,MENUNULL};
  34. struct IntuiText MrGadMenuT2 = {3,1,COMPLEMENT,0,0,NULL,"YES",NULL};
  35. struct MenuItem MrGadItem1 =
  36. {&MrGadItem2,0,0,96,8,ITEMTEXT | COMMSEQ | ITEMENABLED | HIGHCOMP,0,
  37.         (APTR)&MrGadMenuT2,NULL,'Y',NULL,MENUNULL};
  38. struct Menu MrGadMenu = {NULL,0,0,93,0,MENUENABLED,"Yes or No",&MrGadItem1};
  39.  
  40.  /* special structure to keep track of mrgadget and to open it with */
  41. struct MrGadget {
  42.     char *title;     /* title to be given to window structure */
  43.     int ns;        /* number of string gadgets */
  44.     int nb;        /* number of boolean gadgets */
  45.     char **strtext;    /* pointer to pointer to title of each string
  46.              *  and boolean gadget, string will be stored first
  47.              *  then boolean */
  48.     char **getstr;    /* pointer to pointer to storage for each string 
  49.              * gadget. getstr will be sent with a null term. string
  50.              * that is the size of the buffer such as 32 char input
  51.              * you will send a 32 char null terminated string */
  52.  
  53.     /* this rest of this structure is maintained by the functions of the
  54.      * program. they are used for memory allocations and pointers 
  55.      * that the functions require.  do not tamper with */
  56.     struct Window *w;
  57.      struct RastPort *rp;
  58.     struct Gadget *gad; /* memory for gad structures */
  59.     struct IntuiText *itext; /* memory for Text structures */
  60.     struct Border *border; /* memory for borders */
  61.     struct StringInfo *stri; /* memory for string info */
  62.     SHORT  *pairs; /* memory for pairs */
  63.     };
  64.  
  65. struct NewWindow mrgadgetnw = {
  66.     0,0,0,0,1,2,
  67.     GADGETUP | MENUPICK,        /* nw.IDCMPFlags */
  68.     ACTIVATE | WINDOWDRAG,     /* nw.flags    */
  69.     NULL,NULL,NULL,NULL,NULL,
  70.     70,20,640,200,
  71.     WBENCHSCREEN
  72. };
  73.  
  74. /* generic structures use though initialize the gad. structures */
  75. UBYTE UNDOBUFFER[80]; /* same undo buffer for all strings */
  76. struct StringInfo GenStrINFO =
  77. {NULL,UNDOBUFFER,0,20,0,0,0,0,0,0,0,0,NULL};
  78. struct Border GenBorder = {-2,-2,2,0,JAM2,5,NULL,NULL};
  79. struct IntuiText GenText = {3,0,JAM2,0,-12,NULL,NULL,NULL};
  80. struct Gadget GenGadget = {NULL,0,0,0,8,GADGHCOMP,RELVERIFY,
  81.     STRGADGET,(APTR)&GenBorder,NULL,&GenText,NULL,NULL,0,NULL};
  82.  
  83. void
  84. closeMrGadget(mrgad)
  85.     struct MrGadget *mrgad;
  86. {
  87.     int i;
  88.     i = mrgad->ns + mrgad->nb;
  89.     if(mrgad->w) CloseWindow(mrgad->w);
  90.     if(mrgad->gad) FreeMem(mrgad->gad,sizeof(struct Gadget)*i);
  91.     if(mrgad->itext) FreeMem(mrgad->itext,sizeof(struct IntuiText)*i);
  92.     if(mrgad->border) FreeMem(mrgad->border,sizeof(struct Border) * i * 2);
  93.     if(mrgad->stri) FreeMem(mrgad->stri,sizeof(struct StringInfo)* mrgad->ns);
  94.     if(mrgad->pairs) FreeMem(mrgad->pairs,sizeof(SHORT) * i * 10 * 2);
  95. }
  96. int    /* true or false */
  97. openMrGadget(mrgad)
  98.     struct MrGadget *mrgad;
  99. {
  100.     int i, j; /* loop counters */
  101.     int windw;
  102.     int top;
  103.     int width;
  104.     int dostr;
  105.     int gadid;
  106.     char **getptr, **textptr;
  107.     struct Gadget *gad;
  108.     struct IntuiText *itext;
  109.     struct Border *border;
  110.     struct StringInfo *stri;
  111.     SHORT *pairs;
  112.     mrgad->w = NULL; /* window is not open yet */
  113.     mrgad->rp = NULL;
  114. /* get memory for the gadgets stuff */
  115.     i = mrgad->ns + mrgad->nb; /* total the number of gadgets needed */
  116.     mrgad->gad=(struct Gadget *)
  117.             AllocMem(sizeof(struct Gadget) * i,0);
  118.     mrgad->itext=(struct IntuiText *)
  119.             AllocMem(sizeof(struct IntuiText) * i,0);
  120.     mrgad->border=(struct Border *)
  121.             AllocMem(sizeof(struct Border) * i * 2,0);
  122.     if(mrgad->ns)
  123.         mrgad->stri=(struct StringInfo *)
  124.             AllocMem(sizeof(struct StringInfo) * mrgad->ns,0);
  125.     mrgad->pairs = (SHORT *)
  126.             AllocMem(sizeof(SHORT) * i * 10 * 2,0);
  127.     if(mrgad->ns != 0 && ! mrgad->stri) {
  128.         closeMrGadget();
  129.         return(FALSE); /* failed let caller know */
  130.         }
  131.     if(! mrgad->gad || ! mrgad->itext || ! mrgad->border ||
  132.        ! mrgad->pairs ) {
  133.         closeMrGadget();
  134.         return(FALSE); /* failed let caller know */
  135.         }
  136. /* we have the memory now set up the gadgets  */
  137. /* copy all generic information to all of the structures */
  138.     *mrgad->gad = GenGadget;
  139.     *mrgad->itext = GenText;
  140.     *mrgad->border = GenBorder;
  141.     if(mrgad->ns) *mrgad->stri = GenStrINFO; /* be sure you need stri */
  142.  
  143.     gad = mrgad->gad; /* first of gad memory */
  144.     itext = mrgad->itext;
  145.     border = mrgad->border;
  146.     j = mrgad->ns + mrgad->nb;
  147.     *(border + j) = *mrgad->border; /* wont be copied below */
  148.     for(i=1;i < j ;i++) {
  149.         gad++, itext++, border++; /* move all to next one */
  150.         *gad = *mrgad->gad;
  151.         *itext = *mrgad->itext;
  152.         *border = *(border + j) = *mrgad->border;
  153.         }
  154.     stri = mrgad->stri;
  155.     for(i=1;i<mrgad->ns;i++) {
  156.         stri++;
  157.         *stri = *mrgad->stri;
  158.         }
  159.     gad = mrgad->gad; /* first of gad memory */
  160.     itext = mrgad->itext;
  161.     border = mrgad->border;
  162.     pairs = mrgad->pairs;
  163.     stri = mrgad->stri;
  164.  
  165.     getptr = mrgad->getstr;
  166.     textptr = mrgad->strtext;
  167.     gadid = 0; /* all string gadget will be supplied with 0 */
  168.      /* will make the window width at least as wide as the title */
  169.     windw = (strlen(mrgad->title)* 8)+16;
  170.     top = 34; /* first gadget starts 34 pix down */
  171.     for(i=0;i<mrgad->ns + mrgad->nb ;i++) {
  172.         if(i == mrgad->ns && mrgad->nb) top -= 6; /* space for bool */
  173.         if(i<mrgad->ns) dostr = TRUE; /* first build strings */
  174.         else dostr = FALSE; /* then build bool gadgets */
  175.         if(dostr) width = strlen(*getptr)+1; /* null tells how big */
  176.         else width = strlen(*textptr);
  177.         width *= 8; /* each char 8 wide */
  178.         if(! dostr) width += 16; /* for BOOL text */
  179.         else width += 8; /* for string gadget */
  180.         gad->Width = width-2;
  181.         if(windw < width) windw = width;
  182.         for(j=0;j<10;j++) {
  183.            if(dostr) {
  184.             *(pairs + j) = -3; /* outside square */
  185.             *(pairs + j + 10) = 0;    /* inside square */
  186.             }
  187.            else {
  188.             *(pairs + j) = 0; /* outside square */
  189.             *(pairs + j + 10) = 3;    /* inside square */
  190.             }
  191.            } /* end for */
  192.         if(dostr) {
  193.                 /* pairs X quad. */
  194.             *(pairs + 2) = *(pairs + 4) = width;
  195.             *(pairs + 2 + 10) = *(pairs + 4 + 10) = width - 3;
  196.                 /* pairs Y quad. */
  197.             *(pairs + 5) = *(pairs + 7) = 14;
  198.             *(pairs + 5 + 10) = *(pairs + 7 + 10) =    11;
  199.             }
  200.         else {
  201.                 /* pairs X quad. */
  202.             *(pairs + 2) = *(pairs + 4) = width;
  203.             *(pairs + 2 + 10) = *(pairs + 4 + 10) = width - 3;
  204.                 /* pairs Y quad. */
  205.             *(pairs + 5) = *(pairs + 7) = 16;
  206.             *(pairs + 5 + 10) = *(pairs + 7 + 10) =    13;
  207.             }
  208.         border-> XY = pairs;
  209.         border-> NextBorder = (border + 1);
  210.         gad->GadgetRender = (APTR) border; 
  211.         border++; /* next border for small square */
  212.         pairs += 10; /* move to small pairs */
  213.         border->XY = pairs;
  214.         border->FrontPen = 3;
  215.         border++;
  216.         pairs += 10;
  217.         j = width; /* still hold width of get string */
  218.         width = strlen(*textptr);
  219.         width *= 8; /* char 8 pix wide */
  220.         if(windw < width) windw = width;
  221.         if(dostr){
  222.             itext->TopEdge = -12; /* print text above gadget */
  223.             itext->LeftEdge = (j - width) / 2; /* center text */
  224.             }
  225.         else {
  226.             itext->TopEdge = 3;
  227.             itext->LeftEdge = 8;
  228.             }
  229.         itext->IText = *textptr;
  230.         gad->GadgetText = itext;
  231.         itext++;
  232.         if(dostr) {
  233.             stri->MaxChars = strlen(*getptr)+1; /*count term.NULL*/
  234.             stri->Buffer = *getptr;
  235.             **getptr = '\0'; /* null string */
  236.             gad->SpecialInfo = (APTR) stri;
  237.             stri++;
  238.             }
  239.         else gad->Height = 13;
  240.         gad->NextGadget = (gad + 1);
  241.         gad->LeftEdge = 4; /* should be changed later onto center*/
  242.         gad->TopEdge = top;
  243.         if(dostr) {
  244.         gad->GadgetType = STRGADGET;
  245.         getptr++;
  246.         top +=26; /* move past to the next gadget */
  247.         }
  248.         else {
  249.         gad->GadgetType = BOOLGADGET;
  250.         gadid++;
  251.         top +=20; /* move past to the next gadget */
  252.         }
  253.         gad->GadgetID = gadid; /* all string gadgets get 0 bool 1-2-3-- */
  254.         textptr++;
  255.         gad++;
  256.         }
  257.     gad--; /* back up a gadget need to null the last NextGadget */
  258.     gad->NextGadget = NULL;
  259.     gad = mrgad->gad;
  260.     
  261.  
  262.     windw += 40; /* give 20 pix a side of widest gadget */
  263.     for(i=0;i<mrgad->ns + mrgad->nb ;i++) {
  264.         gad->LeftEdge = (windw - gad->Width)/2;
  265.         gad++;
  266.         }
  267.     mrgadgetnw.FirstGadget = mrgad->gad;
  268.     mrgadgetnw.Width = windw;
  269.     mrgadgetnw.Height = top;
  270.     mrgadgetnw.Title = mrgad->title;
  271.  
  272.     /* open the window */
  273.     if((mrgad->w = (struct Window *)OpenWindow(&mrgadgetnw))== NULL) {
  274.         closeMrGadget();
  275.         return(FALSE);
  276.         }
  277.      mrgad->rp = mrgad->w->RPort;
  278.     SetDrMd(mrgad->rp,JAM2);
  279.     SetAPen(mrgad->rp,1); /* pen = BLACK */
  280.     SetBPen(mrgad->rp,0); /* background = WHITE */
  281.     return(TRUE);
  282.  
  283. }
  284. int
  285. useMrGadget(mrgad,message)
  286.     struct MrGadget *mrgad;
  287.     char *message; /* a message to be displayed if needed */
  288. {
  289.     struct IntuiMessage *mes;
  290.     int class, code;
  291.     int gadid;    /* gadget ID for return value */
  292.     struct Gadget *gad;
  293.     int  x, y;
  294.     char *space;
  295.  
  296.     space = "                                                                      ";
  297.     x = mrgad->w->Width / 8; /* number of  char across window */
  298.     y = mrgad->w->BorderTop + 8;
  299.     /* clear any possible message at the top of the window */
  300.     Move(mrgad->rp,mrgad->w->BorderLeft,y);
  301.     Text(mrgad->rp,space,x - 1);
  302.     RefreshGadgets(mrgad->gad,mrgad->w,NULL);
  303.     if(*message) {
  304.         y = mrgad->w->BorderTop + 8;
  305.         x = mrgad->w->Width - (strlen(message)*8);
  306.         if(x) x /= 2; /* be sure not to divide by 0 */
  307.         if(x >= 0) {
  308.             Move(mrgad->rp,x,y);
  309.             Text(mrgad->rp,message,strlen(message));
  310.             }
  311.         }
  312.     for(;;)
  313.     {
  314.         if((mes = (struct IntuiMessage *)
  315.                 GetMsg(mrgad->w->UserPort)) == 0L) {
  316.             Wait(1L<<mrgad->w->UserPort->mp_SigBit);
  317.             continue;
  318.          } /* end if */
  319.         class = mes->Class;
  320.         code = mes->Code;
  321.         ReplyMsg(mes);
  322.         gadid = -1;
  323.         switch (class){
  324.             case MENUPICK :    
  325.                if(code != MENUNULL){
  326.                  if(MENUNUM(code) == 0) gadid = ITEMNUM(code)+1;
  327.                   break;
  328.                 }
  329.                 case GADGETUP :    
  330.                 gad = (struct Gadget *) mes->IAddress;
  331.                 gadid = gad->GadgetID;
  332.                                 break;
  333.             } /* switch */
  334.     if(gadid != -1) break;
  335.     } /* for */
  336.     return(gadid);
  337. }
  338. int /* TRUE OR FALSE */
  339. YesNo(question)
  340.     char *question;
  341. {
  342.     struct MrGadget mrgad;
  343.      char *strtext[2], *message;
  344.     int reply, flag;
  345.  
  346.     message =  " ";
  347.     strtext[0] = "YES";
  348.     strtext[1] = "NO";
  349.     mrgad.title = question;
  350.     mrgad.ns = 0; /* no string gadgets */
  351.     mrgad.nb = 2; /* 2 bool gadgets */
  352.     mrgad.strtext = strtext;
  353.     mrgad.getstr = NULL;
  354.     flag = openMrGadget(&mrgad);
  355.     if(! flag) {
  356.         return(-1);
  357.         }
  358.     SetMenuStrip(mrgad.w,&MrGadMenu); /* add the menu */
  359.     for(;;) {
  360.         flag = FALSE;
  361.         reply = useMrGadget(&mrgad,message);
  362.         switch (reply) {
  363.             case 1: /* YES gadget hit */
  364.                 reply = flag = TRUE;
  365.                 break;
  366.             case 2:    /* NO gadget hit */
  367.                 flag = TRUE;
  368.                 reply = FALSE;
  369.                 break;
  370.             } /* end switch */    
  371.         if(flag) break;
  372.         } /* end for */
  373.     if(mrgad.w) ClearMenuStrip(mrgad.w);
  374.     closeMrGadget(&mrgad);
  375.     return(reply);
  376.  
  377. }
  378. /*==================== end of MrGadget functions =======================*/ 
  379. /*  The above functions fit nicely in to a small library to link from   */
  380. /*======================================================================*/
  381. /*====== All following code is to demonstrate the use of MrGadget ======*/
  382. struct IntuitionBase *IntuitionBase;
  383. struct GfxBase *GfxBase;
  384.  
  385. void
  386. Close_shop()
  387. {
  388.     if (GfxBase)        CloseLibrary(GfxBase);
  389.     if (IntuitionBase)     CloseLibrary(IntuitionBase);
  390. }
  391. void 
  392. Startup()
  393. {    /* Open the intuition library. */
  394.      IntuitionBase = (struct IntuitionBase *)
  395.                 OpenLibrary("intuition.library",0);
  396.     GfxBase = (struct GfxBase *)
  397.             OpenLibrary("graphics.library",0);
  398.  
  399.     if(! IntuitionBase || ! GfxBase) {
  400.     /* bad news one or both Libraries did not open */
  401.         Close_shop();
  402.         exit(FALSE);
  403.         }
  404. }
  405. void /* Simple display of 4 string gadgets and 2 BOOL gadgets */
  406. main()
  407. {
  408.     struct MrGadget mrgad;
  409.     char *strtext[6], *getstr[4], *ptr;
  410.     int numstring, numbool, len, i, j, good, code;
  411.     char *message;
  412.  
  413.     Startup();
  414.     numstring = 4;
  415.     numbool = 2;
  416.     strtext[0] = "string gadget #1";
  417.     strtext[1] = "string gadget #2";
  418.     strtext[2] = "string gadget #3";
  419.     strtext[3] = "string gadget #4";
  420.     strtext[4] = "Yes or No mrgadget";
  421.     strtext[5] = "bool gadget #2";
  422.     getstr[0] = "                      ";
  423.     getstr[1] = "                      ";
  424.     getstr[2] = "                      ";
  425.     getstr[3] = "                      ";
  426.     len = 5;
  427.     for(j=0;j<numstring;j++) { /* build  different size getstr buffers */
  428.         ptr = getstr[j];
  429.         for(i=0;i<len * (j+1);i++){
  430.             *ptr = ' ';
  431.             ptr++;
  432.             } /* end for i */
  433.         *ptr='\0';  /* each one is filled to size, then ended in NULL */
  434.         } /* end for j */
  435.     mrgad.title = "MrGadget in Action!";
  436.     mrgad.ns = numstring;
  437.     mrgad.nb = numbool;
  438.     mrgad.strtext = strtext;
  439.     mrgad.getstr = getstr;
  440.     code = openMrGadget(&mrgad);
  441.     if(! code) {
  442.         printf("MrGadget failed\n");
  443.         Close_shop();
  444.         exit(0);
  445.         }
  446.     message = "hello world"; /* send a message to start with */
  447.     for(;;) {
  448.         good = FALSE;
  449.         code = useMrGadget(&mrgad,message);
  450.         switch (code) {
  451.             case 0: /* user returned on string gadget */
  452.                 for(i=0;i<numstring;i++) /* display them */
  453.                         printf("%s\n",getstr[i]);
  454.                 message = "Returned on a string";
  455.                 break;
  456.             case 1: /* first gadget is equal to 1 */
  457.                 printf("bool gadget #1\n");
  458.                 message = "Hit BOOL gadget 1";
  459.                 good = YesNo("Quit this time?");
  460.                 break;
  461.             case 2: /* second gadet is equal to 2 */
  462.                 printf("bool gadget #2\n");
  463.                 message = "Hit BOOL gadget 2";
  464.                 break;
  465.             } /* end switch */
  466.         printf ("value returned from useMrGadget = %d\n",code);
  467.       if(good) break; /* good is changed by the YesNo function */
  468.    } /* end endless for */
  469.     closeMrGadget(&mrgad);
  470.     Close_shop();
  471. }
  472.